<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="./src/vue.js"></script>
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <h3 id="h">姓名:{{name}}</h3>
      <button @click="setName">setName</button>
      <component :is="com"></component>
      <button @click="change('login')">登录</button>
      <button @click="change('regist')">注册</button>
    </div>
    <template id="login">
      <div>
        <h3>登录</h3>
      </div>
    </template>
    <template id="regist">
      <div>
        <h3>注册</h3>
      </div>
    </template>
    <script>
      Vue.config.productionTip = false; // 关闭控制台生产提示
      Vue.config.devtools = false; // 关闭控制台vue devtools调试工具
      const login = {
        template: "#login",
        data() {
          return {
            timer: null,
          };
        },
        created() {
          this.timer = setInterval(() => {
            console.log("----------");
          }, 1000);
        },
        beforeDestroy() {
          clearInterval(this.timer);
          console.log("login 被销毁了");
        },
      };
      const regist = {
        template: "#regist",
        beforeDestroy() {
          console.log("regist 被销毁了");
        },
      };
      const vm = new Vue({
        el: "#app",
        data: {
          name: "小明",
          com: "login",
        },
        methods: {
          setName() {
            this.name = "小王" + Date.now();
          },
          change(type) {
            this.com = type;
          },
        },
        // 以下四个钩子是初始渲染阶段的函数：它们四个只执行一次，后续数据更新时，组件重新渲染，它们不会再执行了。
        beforeCreate() {
          // 组件实例化之后执行的钩子，此时可以得到一个this实例对象，只是这个this还没有初始化绑定data\methods\computed等。只是一个最初始的this对象。
          const self = this;
          console.log("beforeCreate: ", self);
        },
        created() {
          // this实例继续初始化data\methods\computed这些内容，填充this实例。
          // 组件初始化的请求放在这里发送: 这是最早能够获取data和methods的地方。请求的结果可以保存到data上。
          const self = this;
          console.log("beforeCreate: ", self);
        },
        beforeMount() {
          // 组件开始渲染之前执行的钩子函数。此时组件模板还没有被编译，获取的DOM还是初始DOM。
          console.log(document.getElementById("h").innerText);
        },
        mounted() {
          // 组件渲染完成之后执行的钩子函数。此时获取的DOM已经是最新的DOM。
          // 最早能够操作DOM的钩子
          console.log(document.getElementById("h"));
        },
        // 更新阶段的两个钩子函数：它们会执行多次，当数据改变触发页面渲染，就会执行。
        beforeUpdate() {
          // 数据更新之后，DOM渲染之前执行的函数。此时数据是最新的，DOM是旧DOM。数据已经更新了，DOM还没有渲染。
          // console.log(this.name);
          // console.log(document.getElementById("h").innerText);
        },
        updated() {
          // 新的DOM已经渲染完成，数据和DOM都是最新的。updated()和beforeUpdate()之间的流程会进行虚拟DOM的重新生成以及Diff算法的对比
          console.log(this.name);
          console.log(document.getElementById("h").innerText);
        },
        // 组件销毁阶段执行的两个钩子函数。
        beforeDestroy() {
          // 销毁前，清理定时器，事件监听(addEventListener)等元素js的事件。这些事件都不受vue的控制。当组件销毁的时候，这些事件不会消失。
        },
        components: {
          login,
          regist,
        },
      });
      // 最常用的钩子：created|mounted|beforeDestroy
    </script>
  </body>
</html>
